<?php

namespace libs\database\pdo;

class query extends \libs\database{
    
    public static $_connection;
    
    protected $_connector;

    protected $_from;

    protected $_fields;

    protected $_limit;
    
    protected $_join;

    protected $_offset;

    protected $_order;

    protected $_direction;

    protected $_where;
    
    protected $_query;
    
    protected $_prepare;
    
    public function __construct(\PDO $db) 
    {
        self::$_connection = $db;
    }
    
    public function getAll($tabela)
    {
        $query = "SELECT * FROM {$tabela}"; 
        return $this->_SELECT($query);
    }
    
    
    public function get_where($tabela, $where = array())
    {
        $template = 'SELECT * FROM %s WHERE %s';
        
        $_where = array();
        
        foreach($where as $column=>$value)
        {
            $_where[] = "{$column}= ?";
        }
        
        $_where = implode(' AND ',$_where);
        
        $_values = array_values($where);
        
        $query = sprintf($template,$tabela,$_where);
        
        return $this->_SELECT($query,$_values);
    }
   
       
    public function select($fields)
    {
        $this->_query = 'SELECT %s FROM %s %s %s %s %s';
        
        $this->_fields = $fields;
        
        return $this;
    }
    
    public function join($tabela,$on,$type='JOIN')
    {
        if(empty($on))
        {
            die('Podaj warunek złączenia tabel.');
        }
        
        $this->_join = "{$type} {$tabela} ON {$on}";
        
        return $this;
    }
    
    public function from($from)
    {
        $this->_from = $from;
        return $this;
    }
    
    public function where($fields,$lacznik = 'AND')
    {
        $_fields = array();
        
        foreach($fields as $column=>$value)
        {
            $prepare = explode('.',$column);
            
            $_fields[] = "{$column} = :$prepare[0]";
            
            $this->_prepare[':'.$prepare[0]] = $value;
        }
        
        $this->_where = ' WHERE '.implode(' '.$lacznik.' ', $_fields);
        
        return $this;
    }
    
    public function order($order)
    {
        $_order = array();
        
        foreach($order as $column=>$direction)
        {
            $_order[] = "{$column} {$direction}";
        }
        
        $this->_order = 'ORDER BY '.implode(',',$_order);
        
        return $this;
    }
    
    public function limit($limit,$page = 1)
    {
        $this->_limit = 'LIMIT '.$limit;
        
        if($page > 1)
        {
            $offset = ($page-1)*$limit;
            
            $this->_limit = $this->_limit = "LIMIT {$offset},{$limit}";
        }
        
        return $this;
    }
    
    public function execute()
    {
        $query = sprintf($this->_query,$this->_fields,$this->_from,$this->_join,$this->_where,$this->_order,$this->_limit);
        
        $stmt = self::$_connection->prepare($query); 
        
        if(is_array($this->_prepare))
        {
            foreach($this->_prepare as $column=>$value)
            {
                $stmt->bindValue($column, $value);
            }
        }
        
        $stmt->execute();
        
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        
        return $result;
    }
    
   public function _SELECT($query,$values = false)
    {
        $stmt = self::$_connection->prepare($query);
        
        $values? $stmt->execute($values) : $stmt->execute();
        
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        
        if($stmt->rowCount() == 0)
        {
            return null;
        }

        return $result;  
    }
    
    public function update($tabela,$pola = array(),$where = array())
    {
        $template = "UPDATE %s SET %s WHERE %s";
        
        $_pola = array();
        
        foreach($pola as $pole=>$wartosc)
        {
            $_pola[] = "{$pole}=:{$pole}";
        }
        
        $_pola = implode(', ',$_pola);
        
        $_where = array();
        
        foreach($where as $key=>$val)
        {
            $_where[] = "{$key}=:{$key}";
        }

        $_where = implode(' AND ', $_where);
        
        $query = sprintf($template,$tabela,$_pola,$_where);
        
        return $this->_UPDATE($query,$pola,$where);
    }
    
    public function _UPDATE($query,$pola,$where)
    {
        $stmt = self::$_connection->prepare($query);
        
        foreach($pola as $kolumna=>$wartosc)
        {
            $stmt->bindValue(":{$kolumna}",$wartosc);
        }
        
        foreach($where as $pole => $wart)
        {
            $stmt->bindValue(":{$pole}",$wart);
        }
        
        return $stmt->execute();
    }
    
    public function insert($tabela,$dane = array())
    {
        
        $pola = implode(',',array_keys($dane));
        
        $pytajniki = preg_replace('/(\w)+/',':$0',$pola);
        
        $query = 'INSERT INTO '.$tabela.' (id,'.$pola.') VALUES ("",'.$pytajniki.')';
        
        $stmt = self::$_connection->prepare($query);
        
        
        foreach($dane as $kolumna=>$wartosc)
        {
            $stmt->bindValue(":{$kolumna}",$wartosc);
        }
        
        return $stmt->execute();
    }
  
    
    public function delete($tabela,$pola = array())
    {
        $template = "DELETE FROM %s WHERE %s";
        
        $_pola = array();
        
        foreach($pola as $pole=>$wartosc)
        {
            $_pola[] = "{$pole}=:{$pole}";   
        }
        
        $_pola = implode(' AND ',$_pola);
        
        $query = sprintf($template,$tabela,$_pola);
        
        $stmt = self::$_connection->prepare($query);
        
        foreach($pola as $kolumna=>$wartosc)
        {
            $stmt->bindValue(":{$kolumna}",$wartosc);
        }
        
        return $stmt->execute();
        
        
    }
    
    public function insert_id()
    {
        return self::$_connection->lastInsertId();   
    }
}

?>
